/**
 * OSAmI: Open Source Ambient Intelligence
 * Copyright (C) 2010 UJF.
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */

package org.osami.gateway.mediator.trigger;

import java.util.Date;

import org.osami.gateway.alarm.IAlarm;
import org.osami.gateway.alarm.Severity;
import org.osami.gateway.type.Temperature;
import org.osgi.service.log.LogService;

import fr.liglab.adele.cilia.Data;

public class MediatorAlarmTrigger {

    /**
     * The lowest temperature that can be tolerate.
     * Set in a metadata property.
     */
    private double minTemp;

    /**
     * The greatest temperature that can be tolerate.
     * Set in a metadata property.
     */
    private double maxTemp;

    /**
     * While the temperature is reach, a Severe alarm is triggered.
     * Set in a metadata property.
     */
    private double severeMin;

    /**
     * While the temperature is reach, a Severe alarm is triggered.
     * Set in a metadata property.
     */
    private double severeMax;

    private static final String ALARM_ID_PREFIX = "TEMPERATURE";

    //Alarm counter
    private static int alarmCount = 0;

    /**
     * Logger, injected by iPOJO.
     */
    private LogService logger;

    /**
     * Check the temperature.
     */
    public Data process(Data data) {
        Data alarm = null;
        final Temperature temperature = (Temperature) data.getContent();
        final double value = temperature.getTemperature();

        // Check if an alarm should be triggered
        if (value < minTemp) {
            if (value < severeMin) {
                alarm = createAlarm(temperature, (Date) data.getTimestamp(), "The temperature is lower than " + severeMin + " ! temperature: "
                        + value, Severity.SEVERE);
            } else {
                alarm = createAlarm(temperature, (Date) data.getTimestamp(), "The temperature is lower than " + minTemp + " ! temperature: " + value,
                        Severity.WARNING);
            }
        } else if (value > maxTemp) {
            if (value > severeMax) {
                alarm = createAlarm(temperature, (Date) data.getTimestamp(), "The temperature is greater than " + severeMax + " ! temperature: "
                        + value, Severity.SEVERE);
            } else {
                alarm = createAlarm(temperature, (Date) data.getTimestamp(), "The temperature is greater than " + maxTemp + " ! temperature: "
                        + value, Severity.WARNING);
            }
        }

        return alarm == null ? data : alarm;
    }

    /**
     * Create a data alarm with the given message, temperature and timestamp.
     */
    private Data createAlarm(Temperature temp, Date pTimestamp, String message, Severity severity) {
        IAlarm ialarm = new IAlarmImpl(temp, pTimestamp, message, severity);
        Data data = new Data(ialarm);
        data.setProperty(Temperature.class.getName(), temp);
        data.setType(IAlarm.class.getName());
        data.setProperty(Severity.class.getName(), ialarm.getSeverity());
        return data;
    }

    /**
     * IAlarm implementation.
     */
    private class IAlarmImpl implements IAlarm {

        private final String message;

        private final Date timestamp;

        private final String identifier;

        private final Severity severity;

        /**
         * Parse the data.
         * @param data
         */
        public IAlarmImpl(Temperature temperature, Date pTimestamp, String pMessage, Severity pSeverity) {
            message = pMessage;
            timestamp = pTimestamp;
            identifier = temperature.getGatewayId() + "-" + ALARM_ID_PREFIX + "-" + timestamp.getTime() + "-" + alarmCount++;
            severity = pSeverity;
        }

        public Severity getSeverity() {
            return severity;
        }

        public String getMessage() {
            return message;
        }

        public String getIdentifier() {
            return identifier;
        }

        public Date getGenerationDate() {
            return timestamp;
        }

        public void disengage() {
            // TODO Should I do something ?
        }

        @Override
        public String toString() {
            return message;
        }
    }

}
